package com.jsn.buildbase.home

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.jsn.baselibx.glide.arch.SingleLiveEvent
import com.jsn.baselibx.utils.Logs
import com.jsn.buildbase.data.TalksRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


//来自kotlin文档: break 和 continue 在内联的 lambda 表达式中还不可用，但我们也计划支持它们。
//（所以lambda里面不能随便写奥）
internal inline fun <reified T> ViewModel.doData(
    crossinline start: () -> Unit,
    noinline block: suspend CoroutineScope.() -> T,
    noinline handleData: (T) -> Unit,
    crossinline handelError: (Throwable) -> Unit,
    crossinline end: () -> Unit
) {
    viewModelScope.launch {//新的执行上下文
        try {
            start() //新执行上下文中调用 lambda ,需要告诉编译器 是crossinline
            val t:T = block()
            Logs.e(T::class.java.canonicalName) //记录下实体类的类型
            handleData.invoke(t)
        } catch (e: Throwable) {
            handelError(e)
        } finally {
            end()
        }
    }
}
class HomeViewModel(private val talksRepository: TalksRepository) : ViewModel() {
   /* private val viewModelJob = SupervisorJob()
    *//**
     * This is the main scope for all coroutines launched by MainViewModel.
     * Since we pass viewModelJob, you can cancel all coroutines
     * launched by uiScope by calling viewModelJob.cancel()
     *//*
    private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

    *//**
     * Cancel all coroutines when the ViewModel is cleared
     *//*
    override fun onCleared() {
        super.onCleared()
        viewModelJob.cancel()
    }*/

    var size = "1"

    val text = MutableLiveData<String>().apply { }

    private val _msg = SingleLiveEvent<String>()

    val msg: LiveData<String>
        get() = _msg

    val _buttonEnabled = MutableLiveData<Boolean>().apply { value = true }

    val buttonEnabled: LiveData<Boolean>
        get() = _buttonEnabled

    fun fetchTalksByText() {
        if (text.value.isNullOrBlank()) {
            _msg.value = "text for search can not be empty"
        } else {
            doData<String>(
                start = { _buttonEnabled.value = false },
                block = {
                     talksRepository.talksByTextRemote(text.value!!, size) },
                handleData = {
                    val data = it
                    //...handle data
                },
                handelError = {
                    val error = it
                    //...handle error
                    _msg.value = "${it.message}+${it.stackTrace}"
                },
                end = { _buttonEnabled.value = true })
        }
    }


    fun _fetchTalksByText() {
        if (text.value.isNullOrBlank()) {
            _msg.value = "text can not be empty"
        } else {
            viewModelScope.launch {
                try {
                    _buttonEnabled.value = false
                    val talksByTextRemote = talksRepository.talksByTextRemote(text.value!!, size)
                    _msg.value = "data fetch"

                } catch (e: Throwable) {
                    _msg.value = "${e.message}+${e.stackTrace}"
                } finally {
                    _buttonEnabled.value = true
                }
            }
        }
    }


}